#include "stdafx.h"
#include "UI.h"
#include <map>

struct X_MAP_MESSAGE
{
    UINT    nMsg;
    LPCTSTR lpszMsg;
};

#ifdef _UNICODE
#define DEFINE_MESSAGE(wm)  { wm, _T(#wm) }
#else
#define DEFINE_MESSAGE(wm)  { wm, #wm }
#endif

// All message text
static const X_MAP_MESSAGE allMessages[] =
{
    DEFINE_MESSAGE(WM_NULL),
    DEFINE_MESSAGE(WM_CREATE),
    DEFINE_MESSAGE(WM_DESTROY),
    DEFINE_MESSAGE(WM_MOVE),
    DEFINE_MESSAGE(WM_SIZE),
    DEFINE_MESSAGE(WM_ACTIVATE),
    DEFINE_MESSAGE(WM_SETFOCUS),
    DEFINE_MESSAGE(WM_KILLFOCUS),
    DEFINE_MESSAGE(WM_ENABLE),
    DEFINE_MESSAGE(WM_SETREDRAW),
    DEFINE_MESSAGE(WM_SETTEXT),
    DEFINE_MESSAGE(WM_GETTEXT),
    DEFINE_MESSAGE(WM_GETTEXTLENGTH),
    DEFINE_MESSAGE(WM_PAINT),
    DEFINE_MESSAGE(WM_CLOSE),
    DEFINE_MESSAGE(WM_QUERYENDSESSION),
    DEFINE_MESSAGE(WM_QUIT),
    DEFINE_MESSAGE(WM_QUERYOPEN),
    DEFINE_MESSAGE(WM_ERASEBKGND),
    DEFINE_MESSAGE(WM_SYSCOLORCHANGE),
    DEFINE_MESSAGE(WM_ENDSESSION),
    DEFINE_MESSAGE(WM_SHOWWINDOW),
    DEFINE_MESSAGE(WM_CTLCOLORMSGBOX),
    DEFINE_MESSAGE(WM_CTLCOLOREDIT),
    DEFINE_MESSAGE(WM_CTLCOLORLISTBOX),
    DEFINE_MESSAGE(WM_CTLCOLORBTN),
    DEFINE_MESSAGE(WM_CTLCOLORDLG),
    DEFINE_MESSAGE(WM_CTLCOLORSCROLLBAR),
    DEFINE_MESSAGE(WM_CTLCOLORSTATIC),
    DEFINE_MESSAGE(OCM_COMMAND),
    DEFINE_MESSAGE(OCM_CTLCOLORBTN),
    DEFINE_MESSAGE(OCM_CTLCOLOREDIT),
    DEFINE_MESSAGE(OCM_CTLCOLORDLG),
    DEFINE_MESSAGE(OCM_CTLCOLORLISTBOX),
    DEFINE_MESSAGE(OCM_CTLCOLORMSGBOX),
    DEFINE_MESSAGE(OCM_CTLCOLORSCROLLBAR),
    DEFINE_MESSAGE(OCM_CTLCOLORSTATIC),
    DEFINE_MESSAGE(OCM_DRAWITEM),
    DEFINE_MESSAGE(OCM_MEASUREITEM),
    DEFINE_MESSAGE(OCM_DELETEITEM),
    DEFINE_MESSAGE(OCM_VKEYTOITEM),
    DEFINE_MESSAGE(OCM_CHARTOITEM),
    DEFINE_MESSAGE(OCM_COMPAREITEM),
    DEFINE_MESSAGE(OCM_HSCROLL),
    DEFINE_MESSAGE(OCM_VSCROLL),
    DEFINE_MESSAGE(OCM_PARENTNOTIFY),
    DEFINE_MESSAGE(OCM_NOTIFY),
    DEFINE_MESSAGE(WM_WININICHANGE),
    DEFINE_MESSAGE(WM_SETTINGCHANGE),
    DEFINE_MESSAGE(WM_DEVMODECHANGE),
    DEFINE_MESSAGE(WM_ACTIVATEAPP),
    DEFINE_MESSAGE(WM_FONTCHANGE),
    DEFINE_MESSAGE(WM_TIMECHANGE),
    DEFINE_MESSAGE(WM_CANCELMODE),
    DEFINE_MESSAGE(WM_SETCURSOR),
    DEFINE_MESSAGE(WM_MOUSEACTIVATE),
    DEFINE_MESSAGE(WM_CHILDACTIVATE),
    DEFINE_MESSAGE(WM_QUEUESYNC),
    DEFINE_MESSAGE(WM_GETMINMAXINFO),
    DEFINE_MESSAGE(WM_ICONERASEBKGND),
    DEFINE_MESSAGE(WM_NEXTDLGCTL),
    DEFINE_MESSAGE(WM_SPOOLERSTATUS),
    DEFINE_MESSAGE(WM_DRAWITEM),
    DEFINE_MESSAGE(WM_MEASUREITEM),
    DEFINE_MESSAGE(WM_DELETEITEM),
    DEFINE_MESSAGE(WM_VKEYTOITEM),
    DEFINE_MESSAGE(WM_CHARTOITEM),
    DEFINE_MESSAGE(WM_SETFONT),
    DEFINE_MESSAGE(WM_GETFONT),
    DEFINE_MESSAGE(WM_QUERYDRAGICON),
    DEFINE_MESSAGE(WM_COMPAREITEM),
    DEFINE_MESSAGE(WM_COMPACTING),
    DEFINE_MESSAGE(WM_NCCREATE),
    DEFINE_MESSAGE(WM_NCDESTROY),
    DEFINE_MESSAGE(WM_NCCALCSIZE),
    DEFINE_MESSAGE(WM_NCHITTEST),
    DEFINE_MESSAGE(WM_NCPAINT),
    DEFINE_MESSAGE(WM_NCACTIVATE),
    DEFINE_MESSAGE(WM_GETDLGCODE),
    DEFINE_MESSAGE(WM_NCMOUSEMOVE),
    DEFINE_MESSAGE(WM_NCLBUTTONDOWN),
    DEFINE_MESSAGE(WM_NCLBUTTONUP),
    DEFINE_MESSAGE(WM_NCLBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_NCRBUTTONDOWN),
    DEFINE_MESSAGE(WM_NCRBUTTONUP),
    DEFINE_MESSAGE(WM_NCRBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_NCMBUTTONDOWN),
    DEFINE_MESSAGE(WM_NCMBUTTONUP),
    DEFINE_MESSAGE(WM_NCMBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_KEYDOWN),
    DEFINE_MESSAGE(WM_KEYUP),
    DEFINE_MESSAGE(WM_CHAR),
    DEFINE_MESSAGE(WM_DEADCHAR),
    DEFINE_MESSAGE(WM_SYSKEYDOWN),
    DEFINE_MESSAGE(WM_SYSKEYUP),
    DEFINE_MESSAGE(WM_SYSCHAR),
    DEFINE_MESSAGE(WM_SYSDEADCHAR),
    DEFINE_MESSAGE(WM_KEYLAST),
    DEFINE_MESSAGE(WM_INITDIALOG),
    DEFINE_MESSAGE(WM_COMMAND),
    DEFINE_MESSAGE(WM_SYSCOMMAND),
    DEFINE_MESSAGE(WM_TIMER),
    DEFINE_MESSAGE(WM_HSCROLL),
    DEFINE_MESSAGE(WM_VSCROLL),
    DEFINE_MESSAGE(WM_INITMENU),
    DEFINE_MESSAGE(WM_INITMENUPOPUP),
    DEFINE_MESSAGE(WM_MENURBUTTONUP),
    DEFINE_MESSAGE(WM_MENUDRAG),
    DEFINE_MESSAGE(WM_MENUGETOBJECT),
    DEFINE_MESSAGE(WM_UNINITMENUPOPUP),
    DEFINE_MESSAGE(WM_MENUCOMMAND),
    DEFINE_MESSAGE(WM_MENUSELECT),
    DEFINE_MESSAGE(WM_MENUCHAR),
    DEFINE_MESSAGE(WM_ENTERIDLE),
    DEFINE_MESSAGE(WM_MOUSEWHEEL),
    DEFINE_MESSAGE(WM_MOUSEMOVE),
    DEFINE_MESSAGE(WM_LBUTTONDOWN),
    DEFINE_MESSAGE(WM_LBUTTONUP),
    DEFINE_MESSAGE(WM_LBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_RBUTTONDOWN),
    DEFINE_MESSAGE(WM_RBUTTONUP),
    DEFINE_MESSAGE(WM_RBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_MBUTTONDOWN),
    DEFINE_MESSAGE(WM_MBUTTONUP),
    DEFINE_MESSAGE(WM_MBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_PARENTNOTIFY),
    DEFINE_MESSAGE(WM_MDICREATE),
    DEFINE_MESSAGE(WM_MDIDESTROY),
    DEFINE_MESSAGE(WM_MDIACTIVATE),
    DEFINE_MESSAGE(WM_MDIRESTORE),
    DEFINE_MESSAGE(WM_MDINEXT),
    DEFINE_MESSAGE(WM_MDIMAXIMIZE),
    DEFINE_MESSAGE(WM_MDITILE),
    DEFINE_MESSAGE(WM_MDICASCADE),
    DEFINE_MESSAGE(WM_MDIICONARRANGE),
    DEFINE_MESSAGE(WM_MDIGETACTIVE),
    DEFINE_MESSAGE(WM_MDISETMENU),
    DEFINE_MESSAGE(WM_ENTERSIZEMOVE),
    DEFINE_MESSAGE(WM_EXITSIZEMOVE),
    DEFINE_MESSAGE(WM_DROPFILES),
    DEFINE_MESSAGE(WM_MDIREFRESHMENU),
    DEFINE_MESSAGE(WM_CUT),
    DEFINE_MESSAGE(WM_COPYDATA),
    DEFINE_MESSAGE(WM_COPY),
    DEFINE_MESSAGE(WM_PASTE),
    DEFINE_MESSAGE(WM_CLEAR),
    DEFINE_MESSAGE(WM_UNDO),
    DEFINE_MESSAGE(WM_RENDERFORMAT),
    DEFINE_MESSAGE(WM_RENDERALLFORMATS),
    DEFINE_MESSAGE(WM_DESTROYCLIPBOARD),
    DEFINE_MESSAGE(WM_DRAWCLIPBOARD),
    DEFINE_MESSAGE(WM_PAINTCLIPBOARD),
    DEFINE_MESSAGE(WM_VSCROLLCLIPBOARD),
    DEFINE_MESSAGE(WM_SIZECLIPBOARD),
    DEFINE_MESSAGE(WM_ASKCBFORMATNAME),
    DEFINE_MESSAGE(WM_CHANGECBCHAIN),
    DEFINE_MESSAGE(WM_HSCROLLCLIPBOARD),
    DEFINE_MESSAGE(WM_QUERYNEWPALETTE),
    DEFINE_MESSAGE(WM_PALETTEISCHANGING),
    DEFINE_MESSAGE(WM_PALETTECHANGED),
    DEFINE_MESSAGE(WM_DROPFILES),
    DEFINE_MESSAGE(WM_POWER),
    DEFINE_MESSAGE(WM_WINDOWPOSCHANGED),
    DEFINE_MESSAGE(WM_WINDOWPOSCHANGING),
    // MFC specific messages
    DEFINE_MESSAGE(WM_HELP),
    DEFINE_MESSAGE(WM_NOTIFY),
    DEFINE_MESSAGE(WM_CONTEXTMENU),
    DEFINE_MESSAGE(WM_TCARD),
    DEFINE_MESSAGE(WM_MDIREFRESHMENU),
    DEFINE_MESSAGE(WM_MOVING),
    DEFINE_MESSAGE(WM_STYLECHANGED),
    DEFINE_MESSAGE(WM_STYLECHANGING),
    DEFINE_MESSAGE(WM_SIZING),
    DEFINE_MESSAGE(WM_SETHOTKEY),
    DEFINE_MESSAGE(WM_PRINT),
    DEFINE_MESSAGE(WM_PRINTCLIENT),
    DEFINE_MESSAGE(WM_POWERBROADCAST),
    DEFINE_MESSAGE(WM_HOTKEY),
    DEFINE_MESSAGE(WM_GETICON),
    DEFINE_MESSAGE(WM_EXITMENULOOP),
    DEFINE_MESSAGE(WM_ENTERMENULOOP),
    DEFINE_MESSAGE(WM_DISPLAYCHANGE),
    DEFINE_MESSAGE(WM_STYLECHANGED),
    DEFINE_MESSAGE(WM_STYLECHANGING),
    DEFINE_MESSAGE(WM_GETICON),
    DEFINE_MESSAGE(WM_SETICON),
    DEFINE_MESSAGE(WM_SIZING),
    DEFINE_MESSAGE(WM_MOVING),
    DEFINE_MESSAGE(WM_CAPTURECHANGED),
    DEFINE_MESSAGE(WM_DEVICECHANGE),
    DEFINE_MESSAGE(WM_PENWINFIRST),
    DEFINE_MESSAGE(WM_PENWINLAST),

#if(WINVER >= 0x0400)
    DEFINE_MESSAGE(WM_PRINT),
    DEFINE_MESSAGE(WM_PRINTCLIENT),
#endif /* WINVER >= 0x0400 */

#if(_WIN32_WINNT >= 0x0500)
    DEFINE_MESSAGE(WM_APPCOMMAND),
#endif /* _WIN32_WINNT >= 0x0500 */

#if(_WIN32_WINNT >= 0x0501)
    DEFINE_MESSAGE(WM_THEMECHANGED),
#endif /* _WIN32_WINNT >= 0x0501 */

#if(_WIN32_WINNT >= 0x0501)
    DEFINE_MESSAGE(WM_CLIPBOARDUPDATE),
#endif /* _WIN32_WINNT >= 0x0501 */

#if(_WIN32_WINNT >= 0x0600)
    DEFINE_MESSAGE(WM_DWMCOMPOSITIONCHANGED),
    DEFINE_MESSAGE(WM_DWMNCRENDERINGCHANGED),
    DEFINE_MESSAGE(WM_DWMCOLORIZATIONCOLORCHANGED),
    DEFINE_MESSAGE(WM_DWMWINDOWMAXIMIZEDCHANGE),
#endif /* _WIN32_WINNT >= 0x0600 */

#if(_WIN32_WINNT >= 0x0601)
    DEFINE_MESSAGE(WM_DWMSENDICONICTHUMBNAIL),
    DEFINE_MESSAGE(WM_DWMSENDICONICLIVEPREVIEWBITMAP),
#endif /* _WIN32_WINNT >= 0x0601 */

#if(WINVER >= 0x0600)
    DEFINE_MESSAGE(WM_GETTITLEBARINFOEX),
#endif /* WINVER >= 0x0600 */

#if(WINVER >= 0x0400)
    DEFINE_MESSAGE(WM_HANDHELDFIRST),
    DEFINE_MESSAGE(WM_HANDHELDLAST),
    DEFINE_MESSAGE(WM_AFXFIRST),
    DEFINE_MESSAGE(WM_AFXLAST),
#endif /* WINVER >= 0x0400 */

#if(WINVER >= 0x0400)
    DEFINE_MESSAGE(WM_APP),
#endif /* WINVER >= 0x0400 */

#if((_WIN32_WINNT >= 0x0400) || (WINVER >= 0x0500))
    DEFINE_MESSAGE(WM_MOUSEHOVER),
    DEFINE_MESSAGE(WM_MOUSEENTER),
    DEFINE_MESSAGE(WM_MOUSELEAVE),
#endif

#if(WINVER >= 0x0500)
    DEFINE_MESSAGE(WM_NCMOUSEHOVER),
    DEFINE_MESSAGE(WM_NCMOUSELEAVE),
#endif /* WINVER >= 0x0500 */

#if(WINVER >= 0x0400)
    DEFINE_MESSAGE(WM_IME_SETCONTEXT),
    DEFINE_MESSAGE(WM_IME_NOTIFY),
    DEFINE_MESSAGE(WM_IME_CONTROL),
    DEFINE_MESSAGE(WM_IME_COMPOSITIONFULL),
    DEFINE_MESSAGE(WM_IME_SELECT),
    DEFINE_MESSAGE(WM_IME_CHAR),
#endif /* WINVER >= 0x0400 */

#if(WINVER >= 0x0500)
    DEFINE_MESSAGE(WM_IME_REQUEST),
#endif /* WINVER >= 0x0500 */

#if(WINVER >= 0x0400)
    DEFINE_MESSAGE(WM_IME_KEYDOWN),
    DEFINE_MESSAGE(WM_IME_KEYUP),
#endif /* WINVER >= 0x0400 */

    { 0, NULL, }    // end of message list
};

LPCTSTR debugGetMessageName(UINT message)
{
    typedef std::map<UINT, CString> UIMAP;
    static UIMAP msg;
    if (msg.empty())
        for (const X_MAP_MESSAGE* pMsg = allMessages; pMsg->lpszMsg != NULL; pMsg++)
            msg.insert(UIMAP::value_type(pMsg->nMsg, pMsg->lpszMsg));
    auto found = msg.find(message);
    if (found != msg.end())
        return found->second.GetBuffer();
    else
        return _T("UNKNOWN");
}